#include <std.h>
#include <memory.h>
#include <irq.h>
#include <lfbreg.h>

/* This file has functions which link directly to the main ui lfb functions*/

/*LFB region allocation routines*/

/*Concept:
Each gui component-- textbox,frame etc.. allocates an lfb region specifying it's
coordinates.. This allocation does not hold the display data of the component.
It only holds the coordinates of the component image allocation.
When a component gets refreshed,removed or created lfb regions are searched for
the region that needs to be refreshed. All allocations which reserve that region
are called (their redraw function is called)*/


static lfbregion *lr_head,*lr_end;

void init_lfbregion()
{
	lr_head=NULL;	//First region will be in head (background image)
	lr_end=NULL;
}

/*Todo: Try a memcpy in a structure instead of assigning each member*/
lfbregion *allocate_lfbregion(int (*redraw)(int x,int y,int x1,int y1),int x,int y,int x1,int y1)
{
	lfbregion *_new;
	if(lr_head==NULL)	{
		create_head(lfbregion,lr_head);
		_new=lr_head;
	}
	else
		add_node_end(lfbregion,lr_head,_new);
	_new->x=x;
	_new->y=y;
	_new->x1=x1;
	_new->y1=y1;
	_new->redraw=redraw;
	_new->next=NULL;
	lr_end=_new;
	return _new;
}

static lfbregion *find_lfbregion(lfbregion *start,int x,int y,int x1,int y1)
{
	lfbregion *nav;
	if(start==NULL) return NULL;
	for(nav=start;nav!=NULL;nav=nav->next)	{
		if(x>=nav->x && y>=nav->y && x1<=nav->x1 && y1<=nav->y1)	{
			return nav;
		}
	}
	return NULL;
}

/*This function will find the region which consists of the area which was
requested for a redraw and will call the redraw function of the lfbregion which
owns the area*/

#define SCREENX_L 799
#define SCREENY_L 599

int redraw_lfbregion(int x,int y,int x1,int y1)
{
	lfbregion *region_owner,*start;
	start=lr_head;
	if(x<0)
		x=0;
	if(y<0)
		y=0;
	if(x>SCREENX_L)
		x=SCREENX_L;
	if(y>SCREENY_L)
		y=SCREENY_L;
	if(x1<0)
		x1=0;
	if(y1<0)
		y1=0;
	if(x1>SCREENX_L)
		x1=SCREENX_L;
	if(y1>SCREENY_L)
		y1=SCREENY_L;
	while(start!=NULL)	{
		region_owner=find_lfbregion(start,x,y,x1,y);
		region_owner->redraw(x,y,x1,y1);
		start=region_owner->next;
	}
	return NULL;
}
